CC=g++
# -O1的优化：最基本的优化，减少代码大小、编译时间，提升一定的性能。一些优化方案：循环展开（小规模for循环直接展开成计算式）、减少冗余操作（if(flag==true)优化，do not repeat yourself）、小函数内联展开以减少内联开销（其实内联与否和是否使用inline修饰无关，inline只是提示编译器建议内联）、折叠常量表达式直接返回结果之类
# -O2的优化：为适应CPU流水而调整二进制指令顺序（比如说乘法等耗时操作先计算）；对大的函数也内联展开，减少函数调用；检测全局哪些函数变量没有被使用，优化之；SIMD指令（多个标量计算优化成一个单指令向量运算）；优化内存布局（比如将结构体中常被访问的变量提前）
# -O3的优化：可能会增加代码大小，以空间换时间，内联较大的函数；小循环完全展开（小于16次），利用更多的SIMD指令；合并函数；跨文件优化（函数调用链跨.c文件，跨.c文件把函数合并成一个）；分支预测，根据概率对高概率运行的分支优先调度，但是可能有代价
# =================》-O3导致体积增大：内联展开可能使得重复代码过多。编译器bug：如果内联展开的函数，里面递归比较多，栈溢出
# -Ofast的优化：比-O3还要激进，忽略浮点精度，可能会导致浮点运算出问题；使用近似数学函数，比如计算sin本可以用标准库sin函数，现在使用查表近似值；合并更多的分支和循环，提高指令缓存利用率
# -------------------------------------------------------------------------------
# -march=native：生成针对当前cpu架构的优化后的指令，但是可移植性降低，可能无法在其他cpu上运行
# -------------------------------------------------------------------------------
# -flto：链接时优化，消除跨文件调用时的开销，允许跨文件跨编译单元内联优化代码，可以减少二进制体积，提升运行时性能==========》本工程其实可以不用
# -------------------------------------------------------------------------------
# -funroll-loops：展开循环，降低分支跳转带来的开销
# -------------------------------------------------------------------------------
# -fno-exceptions：禁用异常机制，编译时不生成异常处理代码
# -------------------------------------------------------------------------------
# -fno-rtti：禁用RTTI机制，g++是默认开启的。但是如果源码中的结构体或者类没有定义虚函数，编译器也不会为之生成RTTI，所以本工程其实也可以不用
# -------------------------------------------------------------------------------
# -fomit-frame-pointer：忽略帧指针。什么是帧指针：函数运行的时候为了方便调试，专门用一个函数寄存器放当前函数基地址。这个选项可以节省一个寄存器的使用，让CPU有更多的寄存器参与计算工作
# CFLAGS=--std=c++11 -g -O2 -march=native -flto -funroll-loops -fopenmp
CFLAGS=--std=c++11 -Ofast -march=native -flto -funroll-loops -fno-exceptions -fno-rtti -fomit-frame-pointer

TARGETS=alice bob

all: ${TARGETS}

%: %.cpp common.h
	${CC} ${CFLAGS} $< -o $@

clean:
	rm -f ${TARGETS}
